package nl.windgazer.arachne.mixins;

import nl.windgazer.arachne.services.ArachneRenderSupport;
import nl.windgazer.arachne.util.ArachneSymbolConstants;

import org.apache.log4j.Logger;
import org.apache.tapestry5.Asset;
import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.annotations.AfterRender;
import org.apache.tapestry5.annotations.MixinAfter;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.Path;
import org.apache.tapestry5.dom.Element;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.json.JSONObject;
import org.apache.tapestry5.services.javascript.JavaScriptSupport;

@MixinAfter
public class CKEditor {

	private static final Logger logger = Logger.getLogger(CKEditor.class);
	
	private static String SCRIPT_ID = "CKEditorBasePath";

	//Injects and Persists

	@Inject
	private JavaScriptSupport _jss;

	@Inject
	@Path("${" + ArachneSymbolConstants.CKEDITOR_BASEDIR + "}/${" + ArachneSymbolConstants.CKEDITOR_VERSION + "}/ckeditor.js")
	private Asset _baseEditorScript;

	@Inject
	@Path("CKEditor.js")
	private Asset _helperScripts;

	@Inject
	private ArachneRenderSupport _ars;

	//Properties and Parameters

	/**
	 * This parameter can be used to modify the settings of the CKEditor. For detailed possibilities see the
	 * CKEditor API pages at 'http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html'. One additional
	 * feature of note is that I've added a 'Medium' toolbar to the existing set ('Basic' and 'Full'). Where I
	 * found that basic had far too few options and Full was complete overkill, Medium is my personal compromise ;).
	 * You should also be aware that when you supply a config of your own, any defaults defined by this Mixin will
	 * be completely ignored (so the default toolbar will be 'Full', not 'Medium' and width will default to 100%, 
	 * not 500px...).
	 */
	@Parameter(required = false, principal = false, defaultPrefix = BindingConstants.PROP, name = "config")
	private JSONObject _config = null;

	//Components

	//Events

	@AfterRender
	void setupCKEditor(MarkupWriter writer) {
		final String id = writer.getElement().getAttribute("id");
		if (id!=null) {
			_jss.importJavaScriptLibrary(_baseEditorScript);
			_jss.importJavaScriptLibrary(_helperScripts);
			final JSONObject config = new JSONObject(
					"id", id
			);
			if (_config==null) {
				config.put("config", new JSONObject(
						"toolbar", "Medium"
						, "width", "500px"
				));
			} else {
				config.put("config", _config);
			}
			_jss.addInitializerCall("CKEditorHelper", config);
			logger.info("Instantiating CKEditor for :" + id);
			final String scriptUrl = _baseEditorScript.toClientURL();
			final String base = scriptUrl.substring(0, scriptUrl.lastIndexOf('/') + 1);
			final Element head = writer.getDocument().find("html/head");
			if (head!=null&&head.getElementById(SCRIPT_ID) == null) {
				_ars.addScriptHead("var CKEDITOR_BASEPATH = '" + base + "';", true);
			}
		} else {
			writer.getElement().attribute("nottextarea", "CKEDITORFAILURE");
			logger.error(writer.getElement().getName() + " has no ID, cannot create a CKEditor!");
		}
	}

	//Other (check for business-logic, it should not remain here)

}
